#include "candidate.h"
#include "configmanager.h"		// 单例get
#include "userdict.h"  // 包含UserDict头文件（获取IUserDict实例）
#include "IUserDict.h" // 包含接口头文件（类型匹配）

#include <QDebug>
#include <algorithm>

Candidate::Candidate(QObject *parent) : QObject(parent), m_candidateCount(5)
{
	// 初始化列表对应input  都是5个候选词
	// 获取词库处理器实例：先获取IUserDict实现（UserDict单例），再注入DictHandler
	IUserDict* userDict = UserDict::getInstance(); 
    m_dictHandler = DictHandler::getInstance(userDict, this);
    
    // 从配置加载候选词数量
    ConfigManager* configMgr = ConfigManager::getInstance();
    int initCount = configMgr->getValue(InputMethodGroup, "CandidateCount", 5).toInt();
    setCandidateCount(initCount);
    qInfo() << "[Candidate] 初始化候选词数量：" << m_candidateCount;

	// 监听候选词数量变更信号
	connect(configMgr, &ConfigManager::candidateCountChanged, this, [this](int newCnt) {
		setCandidateCount(newCnt);
		// 数量变更 若当前有候选词，立即按新数量截断并通知UI更新
		if (!m_candidates.isEmpty()) {
			if (m_candidates.size() > m_candidateCount)	m_candidates = m_candidates.mid(0, m_candidateCount);
		}
		emit candidatesReady(m_candidates);		// UI刷新
		qInfo() << "[Candidate] 候选词数量实时更新：" << newCnt << "，已刷新当前候选词列表";
	});
}

void Candidate::getCandidatesForPinyin(const QString &pinyin)
{
	// 空拼音输入 那么就清除
	if (pinyin.isEmpty()) {
		m_candidates.clear();
		emit candidatesReady(m_candidates);
		return;
	}
	// syetem里面去获取候选词
	QVector<PinyinCandidate> systemCandidates = m_dictHandler->getCandidates(pinyin, Dict_System);
	QVector<PinyinCandidate> userCandidates = m_dictHandler->getCandidates(pinyin, Dict_User);

	// 合并候选词
	m_candidates = mergeCandidates(systemCandidates, userCandidates);
	// sort
	sortCandidates(m_candidates);

	// limit cnt
	if (m_candidates.size() > m_candidateCount) {
		m_candidates = m_candidates.mid(0, m_candidateCount);
		qDebug() << "[Candidate] 按当前数量截断候选词：" << m_candidates.size() << "/" << m_candidateCount;
	}
	emit candidatesReady(m_candidates);
}

void Candidate::getCandidatesWithContext(const QString &pinyin, const QString &context)
{
	if (pinyin.isEmpty()) {
		m_candidates.clear();
        emit candidatesReady(m_candidates);
        return;
	}
	// enssential
	getCandidatesForPinyin(pinyin);
	if (context.isEmpty())	return;
	// 考虑上下文 排序候选词 
	QVector<PinyinCandidate> contextCandidates = m_dictHandler->getContextCandidates(context);

	// 自定义sort  与上下文相关的优先
	for (const auto& contextCandidate : contextCandidates) {
		// 迭代器去找上下文
		auto it = std::find_if(m_candidates.begin(), m_candidates.end(), [&](const PinyinCandidate& c) {
			return c.text == contextCandidate.text;
		});
		// 优先级提高
		if (it != m_candidates.end()) it->frequency += 50;
	}
	// sort again
	// 重新排序后，按当前 m_candidateCount 截断（实时生效）
	sortCandidates(m_candidates);
	if (m_candidates.size() > m_candidateCount)		m_candidates = m_candidates.mid(0, m_candidateCount);
    emit candidatesReady(m_candidates);
}

QVector<PinyinCandidate> Candidate::currentCandidates() const
{
	return m_candidates;
}

void Candidate::adjustCandidateOrder(const QString &selectedText)
{
	// 更新选择历史
	m_selectionHistory[selectedText]++;
	// 提高词频 未来排序会影响
	m_dictHandler->increaseWordFrequency(selectedText);
}

void Candidate::clear()
{
	m_candidates.clear();
    emit candidatesReady(m_candidates);
}

void Candidate::setCandidateCount(int count)
{
	if (count < 3) {
        count = 3;
        qWarning() << "[Candidate] 候选词数量小于最小值3，自动调整为3";
    }
    if (count > 9) {
        count = 9;
        qWarning() << "[Candidate] 候选词数量大于最大值9，自动调整为9";
    }
    // 仅当数量实际变更时才更新（避免无效赋值）
    if (m_candidateCount != count) {
        m_candidateCount = count;
        qInfo() << "[Candidate] 候选词数量已设置为：" << m_candidateCount;
    }
}

QVector<PinyinCandidate> Candidate::mergeCandidates(const QVector<PinyinCandidate> &systemCandidates, const QVector<PinyinCandidate> &userCandidates)
{
	// 词典系统初始化ans
	QVector<PinyinCandidate> ans = systemCandidates;

	// 合并用户输入候选词 去重 提高用户优先级
	for (const auto& userCandidate : userCandidates) {
		// 迭代器去找上下文
		auto it = std::find_if(ans.begin(), ans.end(), [&](const PinyinCandidate& c) {
			return c.text == userCandidate.text;
		});
		// 优先级提高
		if (it != ans.end()) {
			// 如果系统词库中已有该词，提高其词频
			it->frequency += 100;
			it->isUserWord = true;
		} else ans.append(userCandidate);
	}
	return ans;
}

void Candidate::sortCandidates(QVector<PinyinCandidate> &candidates)
{
	// 词频
	std::sort(candidates.begin(), candidates.end());
	// 根据实时更新的history来调整排序 有factor 作为参照
	for (auto& candidate : candidates) {
		if (m_selectionHistory.contains(candidate.text)) {
			candidate.frequency += m_selectionHistory[candidate.text] * 10;
		}
	}
	std::sort(candidates.begin(), candidates.end());
}
